using System;
using System.Globalization;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Microsoft.Practices.Repository.Tests.Mocks;


namespace Microsoft.Practices.Repository.Tests
{
    [TestFixture]
    public class RepositoryFactoryFixture
    {
        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void InterfaceTypeCannotBeNull()
        {
            string connectionStringName = "MyConnection";
            RepositoryFactory.Create(null, connectionStringName);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void ConnectionStringCannotBeNull()
        {
            RepositoryFactory.Create(typeof(IMockRepository), null);
        }

        [Test]
        public void ShouldReturnConcreteInstanceOfT()
        {
            string connectionStringName = "MyConnection";
            IMockRepository repository = RepositoryFactory.Create<IMockRepository>(connectionStringName);

            Assert.IsInstanceOfType(typeof(IMockRepository), repository);
        }

        [Test]
        public void ShouldReturnInstanceOfTasObject()
        {
            string connectionStringName = "MyConnection";
            object repository = RepositoryFactory.Create(typeof(IMockRepository), connectionStringName);

            Assert.IsNotNull(repository);
            Assert.IsInstanceOfType(typeof(IMockRepository), repository);
        }

        [Test]
        public void ShouldPassConnectionNameToRepositoryConstructor()
        {
            string connectionStringName = "MyConnection";
            IMockRepository repository = RepositoryFactory.Create<IMockRepository>(connectionStringName);

            Assert.AreEqual(((MockRepository)repository).ConnectionName, connectionStringName);
        }

        [Test]
        [ExpectedException(typeof(InvalidOperationException))]
        public void ImplementationTypeShouldInheritsFromTypeOfT()
        {
            string connectionStringName = "MyConnection";
            INotImplementedRepository repository = RepositoryFactory.Create<INotImplementedRepository>(connectionStringName);
        }

        [Test]
        public void ShouldReturnConcreteInstanceOfTWithoutParameters()
        {
            IMockRepository repository = RepositoryFactory.Create<IMockRepository>();

            Assert.IsInstanceOfType(typeof(IMockRepository), repository);
        }

        [Test]
        public void ShouldReturnInstanceOfTasObjectWithoutParameters()
        {
            object repository = RepositoryFactory.Create(typeof(IMockRepository));

            Assert.IsNotNull(repository);
            Assert.IsInstanceOfType(typeof(IMockRepository), repository);
        }

        [Test]
        [ExpectedException(typeof(InvalidOperationException))]
        public void ImplementationTypeShouldInheritsFromTypeOfTWithoutParameters()
        {
            INotImplementedRepository repository = RepositoryFactory.Create<INotImplementedRepository>();
        }

        [Test]
        [ExpectedException(typeof(RepositoryFailureException))]
        public void ShouldBeEnabledToThrowRepositoryFailureException()
        {
            RepositoryFailureException ex = new RepositoryFailureException(new Exception());

            Assert.IsNotNull(ex);
            throw ex;
        }

        [Test]
        [ExpectedException(typeof(RepositoryValidationException))]
        public void ShouldBeEnabledToThrowRepositoryValidationException()
        {
            RepositoryValidationException ex = new RepositoryValidationException("TheField", "TheReason");

            Assert.IsNotNull(ex);
            throw ex;
        }

        [Test]
        [ExpectedException(typeof(RepositoryInvalidParameterException))]
        public void ShouldBeEnabledToThrowArgumentException()
        {
            String fieldName = "theField";
            RepositoryInvalidParameterException ex = new RepositoryInvalidParameterException(fieldName);

            Assert.IsNotNull(ex);
            Assert.AreEqual(String.Format("Invalid Database parameter name: {0}", fieldName), ex.Message);
            throw ex;
        }
        
    }
}
